/*
Copyright 2010-2011 CumulusCloud
http://cumuluscloud.cc

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cumulusCloud.repository.folderdb;

import java.util.Date;
import java.util.Map;

import cumulusCloud.caching.ConcurrentHashMapAmountCache;
import cumulusCloud.common.InformationPath;
import cumulusCloud.common.objects.CloudSession;
import cumulusCloud.folderdb.FolderDB;
import cumulusCloud.repository.SessionRepository;
import cumulusCloud.repository.folderdb.converter.xml.ConverterCloudSessionXml;

public class SessionRepositoryFolderDB implements SessionRepository {
	private final static long expiration = 24*60*60*1000; // 1 day
	private final static long refreshExpiration = expiration - 30*60*1000; // 30 minutes (max 48 times a day)
	protected FolderDB<CloudSession> folderdb;
	protected Map<String, CloudSession> cache = new ConcurrentHashMapAmountCache<String, CloudSession>(1000);

	public SessionRepositoryFolderDB() {
		folderdb = new FolderDB<CloudSession>();
		folderdb.init(InformationPath.getCloudGlobalConfigPath() + "sessions", new ConverterCloudSessionXml());
		cleanExpired();
	}

	private void cleanExpired() {
		long currentTime = new Date().getTime();
		for (CloudSession cs: folderdb.getAllObjects()) {
			if (cs.expiration < currentTime) {
				deleteSession(cs.token);
			}
		}
	}

	@Override
	public boolean deleteSession(String token) {
		cache.remove(token);
		return folderdb.deleteObject(token);
	}
	
	@Override
	public CloudSession getSession(String token) {
		// Retrieve from cache or harddrive
		CloudSession cs = cache.get(token);
		if (cs == null) {
			cs = folderdb.getObject(token);
			if (cs != null) {
				cache.put(token, cs);
			}
		}
		
		// Check if expired
		if (cs != null) {
			long currentTime = new Date().getTime();
			if (cs.expiration < currentTime) {
				// Remove
				deleteSession(token);
				return null;
			} else {
				// Update if more than a quarter
				if ((cs.expiration - refreshExpiration) < (currentTime)) {
					saveSession(cs);
				}
			}
		}
		
		return cs;
	}
	
	@Override
	public boolean saveSession(CloudSession session) {
		session.expiration = new Date().getTime() + expiration;
		cache.put(session.token, session);
		return folderdb.saveObject(session);
	}

}
